package ginp

import (
	"log"
	"net/http"
	"server/pkg/myjwt"
	"strings"

	"github.com/gin-gonic/gin"
)

type ContextPro struct {
	AccountId uint
	*gin.Context
}

func (c *ContextPro) respJson(code int, obj any) {
	c.Log(obj)
	c.JSON(code, obj)
}

func (c *ContextPro) Log(data any) {
	// 生成日志格式并记录
	log.Printf("%s %s %s %d  user_id:%v request:%+v respond:%+v",
		c.ClientIP(),
		c.Request.Method,
		c.Request.URL.Path,
		c.Writer.Status(),
		c.GetLoginUserId(),
		c.Request.Form,
		data,
	)
}

// OkJson 返回OK,形式为JSON
func (c *ContextPro) OkJson() {
	c.respJson(http.StatusOK, gin.H{
		"code": codeOk,
		"msg":  "ok",
	})
}

func (c *ContextPro) GetToken() string {
	signToken := c.Request.Header.Get("Authorization")
	signToken = strings.TrimPrefix(signToken, "Bearer ")
	return signToken
}

// GetLoginUserId 获取登录用户id
// GetLoginUserId 获取登录用户id
func (c *ContextPro) GetLoginUserId() uint {

	if c.AccountId != 0 {
		return c.AccountId
	}

	//需要鉴权
	// 从请求头中获取Token信息
	signToken := c.Request.Header.Get("Authorization")
	signToken = strings.TrimPrefix(signToken, "Bearer ")
	if signToken == "" {
		return 0
	}
	// 解析并验证Token有效性，当校验失败时，响应客户端，并终止后面的处理
	myClaims, err := myjwt.ParserToken(signToken)
	if err != nil {
		return 0
	}

	// 添加类型断言
	if id, ok := myClaims.Id.(float64); ok {
		c.AccountId = uint(id)
		return c.AccountId
	}

	return 0
}

// GetLoginUserId 获取登录用户id

// OkJsonData 返回OK,形式为JSONextra为任意类型数据。
// extra使用场景：data是固定结构体形式，无法再添加字段时可以将其他信息传到extra中，
// 如直接传map,嫌map麻烦也可以是第一个传key，第二个参数val，
// 前端自己处理业务逻辑（前段收到的extra字段是数组形式）
func (c *ContextPro) OkJsonData(data any) {
	c.respJson(200, gin.H{
		"code": codeOk,
		"msg":  "ok",
		"data": data,
		//"extra": extra,
	})
}
func (c *ContextPro) OkHtml(path string) {
	c.HTML(http.StatusOK, path, gin.H{})
}
func (c *ContextPro) OkHtmlJsonFileData(htmlName, JsonFilePath string) {
	data, err := JsonToGinH(JsonFilePath)
	if err != nil {
		println("OkHtmlJsonFileData:" + err.Error())
		data = gin.H{}
	}
	println(data)
	c.HTML(http.StatusOK, htmlName, data)
}

// ErrJsonData 返回OK,形式为JSON
func (c *ContextPro) ErrJsonData(msg string, data any, extra ...any) {
	c.respJson(200, gin.H{
		"code":  codeErr,
		"msg":   msg,
		"data":  data,
		"extra": extra,
	})
}

// ErrJson 返回ERROR,形式为JSON
func (c *ContextPro) ErrJson(strs ...string) {

	msg := "error"
	if len(strs) > 0 {
		msg = strs[0]
	}
	c.respJson(http.StatusOK, gin.H{
		"code": codeErr,
		"msg":  msg,
	})
}
